using System;
using System.Text;

namespace CodeConsult.Nordic.nRF8001.ApplicationControlInterface.Events
{
    public class DecodeHelper
    {
        public enum ByteOrder
        {
            LsbMsb,
            MsbLsb
        }

        private byte[] _buffer;
        private int _index;

        public bool Error { get; private set; }

        public byte[] Buffer
        {
            get
            {
                return _buffer;
            }

            set
            {
                _buffer = value;
                _index = 0;
                Error = false;
            }
        }

        public int BufferLength => Buffer.Length;

        public byte GetByte()
        {
            return CheckLength(sizeof(byte)) ? Buffer[_index++] : default(byte);
        }

        public byte[] GetBytes(int numberOfBytes)
        {
            var res = new byte[numberOfBytes];
            if (CheckLength(numberOfBytes*sizeof (byte)))
            {
                Array.Copy(Buffer, _index, res, 0, numberOfBytes);
                _index += numberOfBytes;
            }

            return res;
        }

        public ushort GetUnsignedShort(ByteOrder byteOrder)
        {
            if (CheckLength(sizeof(ushort)))
            {
                _index += 2;
                if (byteOrder == ByteOrder.LsbMsb)
                {
                    return BitConverter.ToUInt16(Buffer, _index - 2);
                }

                return BitConverter.ToUInt16(Utils.GetReversedBytes(Buffer, _index - 2, 2), 0);
            }

            return default(ushort);
        }

        public uint GetUnsignedInt(ByteOrder byteOrder)
        {
            if (CheckLength(sizeof(uint)))
            {
                _index += 4;
                if (byteOrder == ByteOrder.LsbMsb)
                {
                    return BitConverter.ToUInt32(Buffer, _index - 4);
                }

                return BitConverter.ToUInt32(Utils.GetReversedBytes(Buffer, _index - 4, 4), 0);
            }

            return default(uint);
        }

        public string GetString(int length)
        {
            if (CheckLength(length))
            {
                _index += length;
                return new string(Encoding.UTF8.GetChars(Buffer, _index - length, length));
            }

            return string.Empty;
        }

        private bool CheckLength(int size)
        {
            if (Error) return !Error; // do NOT re-evaluate error

            Error = Buffer.Length < _index + size;

            return !Error;
        }
    }
}
